//
//  MyListViewCell.m
//  PXListView
//
//  Created by Alex Rozanski on 29/05/2010.
//  Copyright 2010 Alex Rozanski. http://perspx.com. All rights reserved.
//

#import "MyListViewCell.h"
#include "common.h"
#include "mupdf/pdf.h"
#import <iso646.h>
#import "DocumentController.h"

#pragma imagepdf

static NSImage *newImageWithPixmap(fz_pixmap *pix, CGDataProviderRef cgdata,NSSize sizeImage)
{
	int w = fz_pixmap_width(ctx, pix);
	int h = fz_pixmap_height(ctx, pix);
	CGColorSpaceRef cgcolor = CGColorSpaceCreateDeviceRGB();
	CGImageRef cgimage = CGImageCreate(w, h, 8, 32, 4 * w, cgcolor, kCGBitmapByteOrderDefault, cgdata, NULL, NO, kCGRenderingIntentDefault);
	NSImage *image = [[NSImage alloc] initWithCGImage:cgimage size:sizeImage];
    CGColorSpaceRelease(cgcolor);
	CGImageRelease(cgimage);
	return image;
}

static fz_display_list *create_page_list(fz_document *doc, fz_page *page)
{
	fz_display_list *list = NULL;
	fz_device *dev = NULL;
    
	fz_var(dev);
	fz_try(ctx)
	{
		list = fz_new_display_list(ctx);
		dev = fz_new_list_device(ctx, list);
		fz_run_page_contents(doc, page, dev, &fz_identity, NULL);
	}
	fz_always(ctx)
	{
		fz_free_device(dev);
	}
	fz_catch(ctx)
	{
		return NULL;
	}
    
	return list;
}

static fz_display_list *create_annot_list(fz_document *doc, fz_page *page)
{
	fz_display_list *list = NULL;
	fz_device *dev = NULL;
    
	fz_var(dev);
	fz_try(ctx)
	{
		fz_annot *annot;
		pdf_document *idoc = pdf_specifics(doc);
        
		if (idoc)
			pdf_update_page(idoc, (pdf_page *)page);
		list = fz_new_display_list(ctx);
		dev = fz_new_list_device(ctx, list);
		for (annot = fz_first_annot(doc, page); annot; annot = fz_next_annot(doc, annot))
			fz_run_annot(doc, page, annot, dev, &fz_identity, NULL);
	}
	fz_always(ctx)
	{
		fz_free_device(dev);
	}
	fz_catch(ctx)
	{
		return NULL;
	}
    
	return list;
}


static fz_pixmap *renderPixmap(fz_document *doc, fz_display_list *page_list, fz_display_list *annot_list, CGSize pageSize, CGSize screenSize, CGRect tileRect, float zoom)
{
	fz_irect bbox;
	fz_rect rect;
	fz_matrix ctm;
	fz_device *dev = NULL;
	fz_pixmap *pix = NULL;
	CGSize scale;
    
	screenSize.width *= screenScale;
	screenSize.height *= screenScale;
	tileRect.origin.x *= screenScale;
	tileRect.origin.y *= screenScale;
	tileRect.size.width *= screenScale;
	tileRect.size.height *= screenScale;
    
	scale = fitPageToScreen(pageSize, screenSize);
	fz_scale(&ctm, scale.width * zoom, scale.height * zoom);
    
	bbox.x0 = tileRect.origin.x;
	bbox.y0 = tileRect.origin.y;
	bbox.x1 = tileRect.origin.x + tileRect.size.width;
	bbox.y1 = tileRect.origin.y + tileRect.size.height;
	fz_rect_from_irect(&rect, &bbox);
    
	fz_var(dev);
	fz_var(pix);
	fz_try(ctx)
	{
		pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox);
		fz_clear_pixmap_with_value(ctx, pix, 255);
        
		dev = fz_new_draw_device(ctx, pix);
		fz_run_display_list(page_list, dev, &ctm, &rect, NULL);
		fz_run_display_list(annot_list, dev, &ctm, &rect, NULL);
	}
	fz_always(ctx)
	{
		fz_free_device(dev);
	}
	fz_catch(ctx)
	{
		fz_drop_pixmap(ctx, pix);
		return NULL;
	}
    
	return pix;
}

#pragma endimagepdf

@implementation MyListViewCell

@synthesize title = _title;
@synthesize image = _image;
@synthesize delegate = _delegate;
// Counter for the amount of current cells
+ (void)updateCount:(BOOL)status {
	static NSInteger count = 0;
	if (status) {
		count++;
	} else {
		count--;
	}
	NSLog(@"Current amount of allocated cells: %ld", (long)count);
}

- (id)	initWithReusableIdentifier: (NSString*)identifier
{
	if(( self = [super initWithReusableIdentifier: identifier] ))
	{
		NSLog(@"Allocating cell");
		[MyListViewCell updateCount:YES];
        numberPageSelect = -1;
	}
	
	return self;
}

- (void) dealloc
{
	NSLog(@"Deallocating cell");
	[MyListViewCell updateCount:NO];
	[_title release];
    [_image release];
    _image = nil;
	[super dealloc];
}

- (void) prepareForReuse
{
	NSLog(@"Reusing cell");
	[_title release];
	_title = nil;
    [_image release];
    _image = nil;
}

- (void)drawRect:(NSRect)dirtyRect
{
	NSRect bounds = [self bounds];
	NSDictionary *attributes = nil;
    //text
    [[NSColor blackColor] set];
    NSSize titleSize = [_title sizeWithAttributes: attributes];
    //draw page
    int numberPage = [_title intValue] - 1;
    NSRect rectTemp = NSMakeRect(0, 0, bounds.size.width -40 , bounds.size.height -20);
    fz_try(ctx)
	{
        fz_rect bound_page;
		page = fz_load_page(_doc, numberPage);
		fz_bound_page(_doc, page, &bound_page);
		pageSize.width = bound_page.x1 - bound_page.x0;
		pageSize.height = bound_page.y1 - bound_page.y0;
        
        if (!page)
            return;
        page_list = create_page_list(_doc, page);
        annot_list = create_annot_list(_doc, page);
        if(!_image)
        {
            CGSize imageViewSize =  CGSizeMake(rectTemp.size.width,rectTemp.size.height);
            CGSize scale = fitPageToScreen(pageSize, imageViewSize);
            CGRect rect = (CGRect){{0.0, 0.0},{pageSize.width * scale.width, pageSize.height * scale.height}};
            image_pix = renderPixmap(_doc, page_list, annot_list, pageSize, imageViewSize , rect, 1.0);
            CGDataProviderRelease(imageData);
            imageData = wrapPixmap(image_pix);
            [_image release];
            _image = nil;
            _image = newImageWithPixmap(image_pix, imageData,rect.size);
            _rectPos = NSMakeRect(20,40, rect.size.width , rect.size.height);
        }
        //draw selected
        if( [self isSelected] )
        {
            [[NSColor selectedControlColor] set];
            attributes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSColor selectedControlTextColor], NSForegroundColorAttributeName, nil];
            NSBezierPath*	roundedRectSelect = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(14,34, _rectPos.size.width + 12, _rectPos.size.height + 12) xRadius: 6.0 yRadius: 6.0];
            [roundedRectSelect fill];
            
             NSRect rectPosText = NSMakeRect(20 + _rectPos.size.width/2 - titleSize.width/2 -10 ,40 -titleSize.height-10,titleSize.width + 20,
                                             titleSize.height);
             NSBezierPath*	roundedRectSelectText = [NSBezierPath bezierPathWithRoundedRect:rectPosText xRadius: 10.0 yRadius: 10.0];
            [roundedRectSelectText fill];
            [_delegate selectItem:numberPage];
            
        }
        //draw text
        
        [_title drawAtPoint: NSMakePoint(20 + _rectPos.size.width/2 - titleSize.width/2 ,40 -titleSize.height-10) withAttributes: attributes];
        //draw boundpage
        NSColor *colorBound = [NSColor colorWithCalibratedRed:0.7 green:0.7 blue:0.7 alpha:0.8];
        [colorBound set];
        NSBezierPath* roundedRect = [NSBezierPath bezierPathWithRoundedRect:_rectPos xRadius:3 yRadius:3];
        [roundedRect setLineWidth:2];
        [roundedRect stroke];
        //draw image
        [_image drawInRect:_rectPos fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
       
    }fz_catch(ctx)
	{
		return;
	}
	[attributes release];
	[super drawRect: dirtyRect];
}

-(NSArray*)	accessibilityAttributeNames
{
	NSMutableArray*	attribs = [[[super accessibilityAttributeNames] mutableCopy] autorelease];
	
	[attribs addObject: NSAccessibilityRoleAttribute];
	[attribs addObject: NSAccessibilityDescriptionAttribute];
	[attribs addObject: NSAccessibilityTitleAttribute];
	[attribs addObject: NSAccessibilityEnabledAttribute];
	
	return attribs;
}

- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute
{
	if( [attribute isEqualToString: NSAccessibilityRoleAttribute]
		or [attribute isEqualToString: NSAccessibilityDescriptionAttribute]
		or [attribute isEqualToString: NSAccessibilityTitleAttribute]
		or [attribute isEqualToString: NSAccessibilityEnabledAttribute] )
	{
		return NO;
	}
	else
		return [super accessibilityIsAttributeSettable: attribute];
}

-(id)	accessibilityAttributeValue: (NSString *)attribute
{
	if( [attribute isEqualToString: NSAccessibilityRoleAttribute] )
	{
		return NSAccessibilityButtonRole;
	}
	else if( [attribute isEqualToString: NSAccessibilityDescriptionAttribute]
			or [attribute isEqualToString: NSAccessibilityTitleAttribute] )
	{
		return _title;
	}
	else if( [attribute isEqualToString: NSAccessibilityEnabledAttribute] )
	{
		return [NSNumber numberWithBool: YES];
	}
	else
		return [super accessibilityAttributeValue: attribute];
}

@end
